// ES5 写法
// const p = new Promise((resolve, reject) => {});
// 声明构造函数，形参为 executor
function Promise(executor) {
    // Promise 对象初始状态
    this.PromiseState = 'pending';
    // Promise 对象初始结果
    this.PromiseResult = null;
    // 声明回调函数初始值
    this.callbacks = [];
    // 保存对象中的 this 变量
    const _this = this;
    // 声明[成功]函数 resolve 函数
    function resolve(data) {
        // console.log(this); // 全局作用域下调用该函数，所以 this 指向 window 对象
        // 修改对象状态时先进行判断
        if (_this.PromiseState !== 'pending') return;
        // 1. 改变对象状态 pending => resolved
        _this.PromiseState = 'resolved'; // fulfilled
        // 2. 设置结果值
        _this.PromiseResult = data;
        // 调用成功的回调函数
        setTimeout(() => {
            _this.callbacks.forEach(item => {
                item.onResolved(data);
            });
        });
    }
    // 声明[失败]函数 reject 函数
    function reject(data) {
        // 修改对象状态时先进行判断
        if (_this.PromiseState !== 'pending') return;
        // 1. 改变对象状态 pending => rejected
        _this.PromiseState = 'rejected';
        // 2. 设置结果值
        _this.PromiseResult = data;
        // 调用失败的回调函数
        setTimeout(() => {
            _this.callbacks.forEach(item => {
                item.onRejected(data);
            });
        });
    }
    try {
        // 同步调用[执行器函数] (resolve, reject) => {}
        executor(resolve, reject);
    } catch(e) {
        // Promise 对象内部抛出错误后，要改变 Promsie 的状态为[失败]并设置结果值
        reject(e);
    } 
}

// p.then(value => {}, reason => {});
// 添加 then() 方法，形参分别为 onResolved，onRejected
Promise.prototype.then = function(onResolved, onRejected) {
    const _this = this;
    // 判断回调函数参数
    if (typeof onRejected !== 'function') {
        onRejected = reason => {
            throw reason;
        }
    }
    if (typeof onResolved !== 'function') {
        onResolved = value => value;
    }
    // 返回值为 Promise 对象
    return new Promise((resolve, reject) => {
        function callback(type) {
            try {
                // 获取回调函数的执行结果
                let result = type(_this.PromiseResult);
                // 判断回调返回值类型
                if (result instanceof Promise) {
                    // 如果是 Promise 对象
                    result.then(v => {
                        resolve(v);
                    }, r => {
                        reject(r);
                    });
                } else {
                    // 返回值为非 Promise 对象，则对象状态为[成功]
                    resolve(result);
                }
            } catch(e) {
                reject(e);
            }
        }
        // 根据 PromiseState 状态来调用不同的回调函数
        if (this.PromiseState === 'resolved') {
            setTimeout(() => {
                callback(onResolved);
            }); 
        } 
        if (this.PromiseState === 'rejected') {
            setTimeout(() => {
                callback(onRejected);
            });
        }
        // 判断 pending 状态
        if (this.PromiseState === 'pending') {
            // 保存回调函数
            this.callbacks.push({
                onResolved: function() {
                    callback(onResolved);
                },
                onRejected: function() {
                    callback(onRejected);
                }
            });
        }
    });
}

// 添加 catch() 方法，形参为 onRejected
Promise.prototype.catch = function(onRejected) {
    return this.then(undefined, onRejected);
}

// 添加 Promise.resolve() 方法
Promise.resolve = function(value) {
    // 返回 Promise 对象
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(v => {
                resolve(v);
            }, r => {
                reject(r);
            });
        } else {
            // 状态设置为[成功]
            resolve(value);
        }
    });
}

// 添加 Promise.reject() 方法
Promise.reject = function(reason) {
    // 返回 Promise 对象
    return new Promise((resolve, reject) => {
        reject(reason);
    });
}

// 添加 Promise.all() 方法
Promise.all = function(promises) {
    // 返回 Promise 对象
    return new Promise((resolve, reject) => {
        // 声明计数变量
        let count = 0;
        // 声明成功结果数组
        let arr = [];
        // 遍历数组内 Promise 对象
        for (let i=0 ; i<promises.length ; i++) {
            promises[i].then(v => {
                count++;
                arr[i] = v;
                if (count === promises.length) {
                    resolve(arr);
                }
            }, r => {
                reject(r);
            });
        }
    })
}

// 添加 Promise.race() 方法
Promise.race = function(promises) {
    // 返回 Promise 对象
    return new Promise((resolve, reject) => {
        // 遍历数组内的 Promise 对象
        for (let i=0 ; i<promises.length ; i++) {
            promises[i].then(v => {
                resolve(v);
            }, r => {
                reject(r);
            });
        }
    });
}

// ES6 写法
// class Promise {
//     // 构造方法
//     constructor(executor) {
//         // Promise 对象初始状态
//         this.PromiseState = 'pending';
//         // Promise 对象初始结果
//         this.PromiseResult = null;
//         // 声明回调函数初始值
//         this.callbacks = [];
//         // 保存对象中的 this 变量
//         const _this = this;
//         // 声明[成功]函数 resolve 函数
//         function resolve(data) {
//             // console.log(this); // 全局作用域下调用该函数，所以 this 指向 window 对象
//             // 修改对象状态时先进行判断
//             if (_this.PromiseState !== 'pending') return;
//             // 1. 改变对象状态 pending => resolved
//             _this.PromiseState = 'resolved'; // fulfilled
//             // 2. 设置结果值
//             _this.PromiseResult = data;
//             // 调用成功的回调函数
//             setTimeout(() => {
//                 _this.callbacks.forEach(item => {
//                     item.onResolved(data);
//                 });
//             });
//         }
//         // 声明[失败]函数 reject 函数
//         function reject(data) {
//             // 修改对象状态时先进行判断
//             if (_this.PromiseState !== 'pending') return;
//             // 1. 改变对象状态 pending => rejected
//             _this.PromiseState = 'rejected';
//             // 2. 设置结果值
//             _this.PromiseResult = data;
//             // 调用失败的回调函数
//             setTimeout(() => {
//                 _this.callbacks.forEach(item => {
//                     item.onRejected(data);
//                 });
//             });
//         }
//         try {
//             // 同步调用[执行器函数] (resolve, reject) => {}
//             executor(resolve, reject);
//         } catch(e) {
//             // Promise 对象内部抛出错误后，要改变 Promsie 的状态为[失败]并设置结果值
//             reject(e);
//         } 
//     }
//     // then() 方法封装
//     then(onResolved, onRejected) {
//         const _this = this;
//         // 判断回调函数参数
//         if (typeof onRejected !== 'function') {
//             onRejected = reason => {
//                 throw reason;
//             }
//         }
//         if (typeof onResolved !== 'function') {
//             onResolved = value => value;
//         }
//         // 返回值为 Promise 对象
//         return new Promise((resolve, reject) => {
//             function callback(type) {
//                 try {
//                     // 获取回调函数的执行结果
//                     let result = type(_this.PromiseResult);
//                     // 判断回调返回值类型
//                     if (result instanceof Promise) {
//                         // 如果是 Promise 对象
//                         result.then(v => {
//                             resolve(v);
//                         }, r => {
//                             reject(r);
//                         });
//                     } else {
//                         // 返回值为非 Promise 对象，则对象状态为[成功]
//                         resolve(result);
//                     }
//                 } catch(e) {
//                     reject(e);
//                 }
//             }
//             // 根据 PromiseState 状态来调用不同的回调函数
//             if (this.PromiseState === 'resolved') {
//                 setTimeout(() => {
//                     callback(onResolved);
//                 }); 
//             } 
//             if (this.PromiseState === 'rejected') {
//                 setTimeout(() => {
//                     callback(onRejected);
//                 });
//             }
//             // 判断 pending 状态
//             if (this.PromiseState === 'pending') {
//                 // 保存回调函数
//                 this.callbacks.push({
//                     onResolved: function() {
//                         callback(onResolved);
//                     },
//                     onRejected: function() {
//                         callback(onRejected);
//                     }
//                 });
//             }
//         });
//     }
//     // catch() 方法封装
//     catch(onRejected) {
//         return this.then(undefined, onRejected);
//     }
//     // Promise.resolve() 方法封装
//     static resolve(value) {
//         // 返回 Promise 对象
//         return new Promise((resolve, reject) => {
//             if (value instanceof Promise) {
//                 value.then(v => {
//                     resolve(v);
//                 }, r => {
//                     reject(r);
//                 });
//             } else {
//                 // 状态设置为[成功]
//                 resolve(value);
//             }
//         });
//     }
//     // Promise.reject() 方法封装
//     static reject(reason) {
//         // 返回 Promise 对象
//         return new Promise((resolve, reject) => {
//             reject(reason);
//         });
//     }
//     // Promise.all() 方法封装
//     static all(promises) {
//         // 返回 Promise 对象
//         return new Promise((resolve, reject) => {
//             // 声明计数变量
//             let count = 0;
//             // 声明成功结果数组
//             let arr = [];
//             // 遍历数组内 Promise 对象
//             for (let i=0 ; i<promises.length ; i++) {
//                 promises[i].then(v => {
//                     count++;
//                     arr[i] = v;
//                     if (count === promises.length) {
//                         resolve(arr);
//                     }
//                 }, r => {
//                     reject(r);
//                 });
//             }
//         })
//     }
//     // Promise.race() 方法封装
//     static race(promises) {
//         // 返回 Promise 对象
//         return new Promise((resolve, reject) => {
//             // 遍历数组内的 Promise 对象
//             for (let i=0 ; i<promises.length ; i++) {
//                 promises[i].then(v => {
//                     resolve(v);
//                 }, r => {
//                     reject(r);
//                 });
//             }
//         });
//     }
// }